package models

import (
	"errors"
	"strings"

	"github.com/tealeg/xlsx"
)

type ExcelParser struct {
	fileHandle  *xlsx.File
	workSheet   *xlsx.Sheet
	FileName    string
	FieldsMap   map[string]int
	FieldsArr   []string
	sourceArray []interface{}
}

func GetExcelParser() *ExcelParser {
	return &ExcelParser{}
}

func (e *ExcelParser) OpenXLSX(name string) error {
	fx, err := xlsx.OpenFileWithRowLimit(name, 1)
	if err != nil {
		return err
	}

	tab := fx.Sheet["Sheet1"]
	oneRow := tab.Row(0)
	if oneRow == nil {
		return errors.New("there is no any data")
	}

	e.FieldsMap = make(map[string]int)
	e.FieldsArr = make([]string, 0)

	for k, v := range oneRow.Cells {
		if len(v.Value) > 0 {
			e.FieldsMap[v.Value] = k
			e.FieldsArr = append(e.FieldsArr, v.Value)
		}
	}

	e.FileName = name
	e.fileHandle = fx
	e.workSheet = tab

	return err
}

func (e *ExcelParser) readExcelAll() error {
	var err error
	e.fileHandle, err = xlsx.OpenFile(e.FileName)
	if err != nil {
		return err
	}

	e.workSheet = e.fileHandle.Sheet["Sheet1"]

	return err
}

func (e *ExcelParser) LoopOneRow(name string, getCellValue func(string, string) error) error {
	fieldIndex, ok := e.FieldsMap[name]
	if ok {
		for i := 1; i < e.workSheet.MaxRow; i++ {
			oneRow := e.workSheet.Row(i)
			err := getCellValue(name, oneRow.Cells[fieldIndex].Value)
			if err != nil {
				return err
			}
		}
	} else {
		return errors.New("find no this field " + name)
	}

	return nil
}

func (e *ExcelParser) GetRowsArray() []interface{} {
	if e.sourceArray == nil {
		err := e.readExcelAll()
		if err != nil {
			return nil
		}

		e.sourceArray = make([]interface{}, 0)
		for i := 1; i < e.workSheet.MaxRow; i++ {
			node := make(map[string]interface{})
			oneRow := e.workSheet.Row(i)
			colCount := len(oneRow.Cells)
			for k, v := range e.FieldsMap {
				if colCount <= v {
					break
				}

				node[k] = interface{}(oneRow.Cells[v].Value)
			}
			e.sourceArray = append(e.sourceArray, interface{}(node))
		}
	}

	return e.sourceArray
}

func (e *ExcelParser) GetFormatFields() string {
	fieldArrStr := "["
	for _, v := range e.FieldsArr {
		fieldArrStr += `"` + v + `"` + ","
	}
	fieldArrStr = strings.TrimRight(fieldArrStr, ",")
	fieldArrStr += "]"

	return fieldArrStr
}
